home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_351 / pdc / libsrc.lzh / LibSrc / Math / mprintf.c < prev    next >
C/C++ Source or Header  |  1990-04-07  |  11KB  |  453 lines

  1. /*
  2.  * Libraries and headers for PDC release 3.3 (C) 1989 Lionel Hummel.
  3.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  4.  * PDC I/O Library (C) 1987 by J.A. Lydiatt.
  5.  *
  6.  * This code is freely redistributable upon the conditions that this 
  7.  * notice remains intact and that modified versions of this file not
  8.  * be included as part of the PDC Software Distribution without the
  9.  * express consent of the copyright holders.  No warrantee of any
  10.  * kind is provided with this code.  For further information, contact:
  11.  *
  12.  *  PDC Software Distribution    Internet:                     BIX:
  13.  *  P.O. Box 4006             or hummel@cs.uiuc.edu            lhummel
  14.  *  Urbana, IL  61801-8801       petersen@uicsrd.csrd.uiuc.edu
  15.  */
  16.  
  17. /*
  18.     fprintf.c - Routines for formatted output
  19.  
  20.     sprintf(buf, fmt, args)            Print to a memory buffer
  21.         char           *buf, *fmt;
  22.         void           *args;
  23.  
  24.     fprintf(fp, fmt, args)            Print to a file pointer
  25.         FILE           *fp;
  26.         char           *fmt;
  27.         void           *args;
  28.  
  29.     printf(fmt, args)            Print to stdout
  30.         char           *fmt;
  31.         void           *args;
  32. */
  33.  
  34. #include <stdio.h>
  35. #include <math.h>
  36.  
  37. #define isupper(x)  ((x) >= 'A' && (x) <= 'Z')
  38. #define islower(x)  ((x) >= 'a' && (x) <= 'z')
  39. #define toupper(x)  ((x) - 'a' + 'A')
  40. #define tolower(x)  ((x) - 'A' + 'a')
  41. #define isdigit(x)  ((x) >= '0' && (x) <= '9')
  42.  
  43. static char    *_hexdigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  44. static char     _doprntbuf[1024];
  45.  
  46. #define TRUE    1
  47. #define FALSE   0
  48.  
  49. #define va_arg(var,mode)    ((mode)(*(mode *)var))
  50.  
  51. static char     buffer[128];
  52.  
  53. char           *
  54. _itoa(num, base)
  55.     int             num;
  56.     unsigned int    base;
  57. {
  58.     char           *ptr;
  59.     int             negative, digit;
  60.     unsigned int    un;
  61.  
  62.     ptr = &buffer[sizeof(buffer) - 1];
  63.     *ptr = '\0';
  64.  
  65.     if (num == 0x80000000) {
  66.         switch (base) {
  67.         case 8:
  68.             return ("20000000000");
  69.             break;
  70.         case 10:
  71.             return ("-2147483648");
  72.             break;
  73.         case 16:
  74.             return ("80000000");
  75.             break;
  76.         default:
  77.             return ("-OOPS-");
  78.         }
  79.     }
  80.  
  81.     if (negative = (num < 0))
  82.         un = (unsigned int) -num;
  83.     else
  84.         un = (unsigned int)  num;
  85.  
  86.     do {
  87.         *(--ptr) = _hexdigits[un % base];
  88.         un /= base;
  89.     } while (un && ptr > &buffer[1]);
  90.  
  91.     if (negative)
  92.         *(--ptr) = '-';
  93.  
  94.     return (ptr);
  95. }
  96.  
  97. char           *
  98. _ftoa(num, precision)
  99.     double          num;
  100.     int             precision;
  101. {
  102.     char           *ptr;
  103.     int             i, negative, digit;
  104.     double          val, frac, intp, temp;
  105.  
  106.     if (precision > 32)
  107.         precision = 6;
  108.  
  109.     if (negative = (num < 0.0))
  110.         num = -num;
  111.  
  112.     num += .5 / pow( (double) 10.0, (double) precision);
  113.     intp = floor(num);
  114.     frac = num - intp;
  115.  
  116.     ptr = buffer;
  117.     for (i = 0; i < precision; i++) {
  118.         frac *= 10.0;
  119.         digit = floor(frac);
  120.         *ptr++ = (digit + '0');
  121.         frac -= digit;
  122.     }
  123.     *ptr++ = '\0';
  124.  
  125.     ptr = &buffer[63 - precision];
  126.     strcpy(ptr, buffer);
  127.  
  128.     *(--ptr) = '.';
  129.  
  130.     do {
  131.         temp = floor(intp / 10.0);
  132.         digit = intp - (temp * 10.0);
  133.         *(--ptr) = (digit + '0');
  134.         intp = temp;
  135.     } while (intp > 0.0);
  136.  
  137.     if (negative)
  138.         *(--ptr) = '-';
  139.  
  140.     return (ptr);
  141. }
  142.  
  143. char           *
  144. _etoa(num, precision)
  145.     double          num;
  146.     int             precision;
  147. {
  148.     char           *ptr;
  149.     int             i, negative, digit, exp, ival;
  150.     double          frac, intp, temp;
  151.  
  152.     if (precision > 32)
  153.         precision = 6;
  154.  
  155.     if (negative = (num < 0.0))
  156.         num = -num;
  157.  
  158.     exp = 0;
  159.  
  160.     if (num != 0.0) {
  161.         while (num >= 10.0) {
  162.             num /= 10.0;
  163.             exp++;
  164.         }
  165.  
  166.         while (num < 1.0) {
  167.             num *= 10.0;
  168.             exp--;
  169.         }
  170.     }
  171.  
  172.     num += .5 / pow( (double) 10.0, (double) precision);
  173.     intp = floor(num);
  174.     frac = num - intp;
  175.  
  176.     ptr = buffer;
  177.     for (i = 0; i < precision; i++) {
  178.         frac *= 10.0;
  179.         digit = floor(frac);
  180.         *ptr++ = (digit + '0');
  181.         frac -= digit;
  182.     }
  183.  
  184.     *ptr++ = 'E';
  185.     if (exp >= 0)
  186.         *ptr++ = '+';
  187.     else {
  188.         *ptr++ = '-';
  189.         exp = -exp;
  190.     }
  191.     for (i = 2; i >= 0; i--) {
  192.         digit = exp % 10;
  193.         ptr[i] = (digit + '0');
  194.         exp /= 10;
  195.     }
  196.     ptr[3] = '\0';
  197.  
  198.     ptr = &buffer[63 - (precision + 6)];
  199.     strcpy(ptr, buffer);
  200.     *(--ptr) = '.';
  201.  
  202.     do {
  203.         temp = floor(intp / 10.0);
  204.         digit = intp - (temp * 10.0);
  205.         *(--ptr) = (digit + '0');
  206.         intp = temp;
  207.     } while (intp > 0.0);
  208.  
  209.     if (negative)
  210.         *(--ptr) = '-';
  211.  
  212.     return (ptr);
  213. }
  214.  
  215. char           *
  216. _gtoa(num, precision)
  217.     double          num;
  218.     int             precision;
  219. {
  220.     char           *ptr;
  221.     double          fsiz;
  222.  
  223.     fsiz = (num < 0.0 ? -num : num);
  224.  
  225.     if (fsiz > 1.0E+20 || fsiz < 1.0E-20)
  226.         return _etoa(num, precision);
  227.  
  228.     ptr = _ftoa(num, precision);
  229.     strcpy(buffer, ptr);
  230.  
  231.     if (precision > 0) {
  232.         ptr = buffer;
  233.         while (*ptr)
  234.             ptr++;
  235.         --ptr;
  236.         while (*ptr == '0')
  237.             *ptr-- = '\0';
  238.     }
  239.     return buffer;
  240. }
  241.  
  242. char           *
  243. _leftjust(str, width, pad)
  244.     char           *str;
  245.     int             width, pad;
  246. {
  247.     char           *ptr;
  248.     int             len;
  249.  
  250.     len = 0;
  251.     ptr = buffer;
  252.     for (ptr = buffer; *str; len++)
  253.         *ptr++ = *str++;
  254.     while (len < width) {
  255.         *ptr++ = pad;
  256.         len++;
  257.     }
  258.     *ptr = '\0';
  259.     return (buffer);
  260. }
  261.  
  262. char           *
  263. _rightjust(str, width, pad)
  264.     char           *str;
  265.     int             width, pad;
  266. {
  267.     char           *ptr;
  268.     int             len;
  269.  
  270.     len = strlen(str);
  271.     ptr = buffer;
  272.     while (len++ < width)
  273.         *ptr++ = pad;
  274.     strcpy(ptr, str);
  275.  
  276.     return (buffer);
  277. }
  278.  
  279. char           *
  280. _justify(str, width, pad)
  281.     char           *str;
  282.     int             width;
  283.     int             pad;
  284. {
  285.     if (width > 0)
  286.         str = _rightjust(str, width, pad);
  287.     else if (width < 0)
  288.         str = _leftjust(str, -width, pad);
  289.     return (str);
  290. }
  291.  
  292.  
  293. _doprnt(fmt, args, buffer)
  294.     char           *fmt, *buffer;
  295.     void           *args;
  296. {
  297.     int             ch, width, just, pad, maxlen;
  298.     char           *aptr = (char *) args;
  299.     char           *fptr = fmt;
  300.     char           *cptr, *tptr;
  301.     double         *dptr;
  302.     char            local[2];
  303.  
  304.     while (*fptr) {
  305.         switch (*fptr) {
  306.         case '%':
  307.             fptr++;
  308.             width = 0;
  309.             maxlen = 1024;
  310.             if (just = ((*fptr) == '-'))
  311.                 fptr++;
  312.             if ((pad = (*fptr)) != '0')
  313.                 pad = ' ';
  314.             if ((*fptr) == '*') {
  315.                 fptr++;
  316.                 width = va_arg(aptr, int);
  317.                 aptr += sizeof(int);
  318.             }
  319.             else {
  320.                 while (isdigit(*fptr)) {
  321.                     width = width * 10 + (*fptr) - '0';
  322.                     fptr++;
  323.                 }
  324.             }
  325.             if (just)
  326.                 width = -width;
  327.             if ((*fptr) == '.') {
  328.                 fptr++;
  329.                 if ((*fptr) == '*') {
  330.                     fptr++;
  331.                     maxlen = va_arg(aptr, int);
  332.                     aptr += sizeof(int);
  333.                 }
  334.                 else {
  335.                     maxlen = 0;
  336.                     while (isdigit(*fptr)) {
  337.                         maxlen = maxlen * 10 + (*fptr) - '0';
  338.                         fptr++;
  339.                     }
  340.                 }
  341.             }
  342.     doagain:
  343.             switch (*fptr) {
  344.             case '%':
  345.                 local[0] = '%';
  346.                 local[1] = '\0';
  347.                 cptr = local;
  348.                 break;
  349.             case 'c':
  350.                 local[0] = va_arg(aptr, int);
  351.                 local[1] = '\0';
  352.                 cptr = local;
  353.                 aptr += sizeof(int);
  354.                 break;
  355.             case 'd':
  356.                 cptr = _itoa(va_arg(aptr, int), 10);
  357.                 aptr += sizeof(int);
  358.                 break;
  359.             case 'e':
  360.                 cptr = _etoa(va_arg(aptr, double), maxlen);
  361.                 aptr += sizeof(double);
  362.                 maxlen = 1024;
  363.                 break;
  364.             case 'f':
  365.                 cptr = _ftoa(va_arg(aptr, double), maxlen);
  366.                 aptr += sizeof(double);
  367.                 maxlen = 1024;
  368.                 break;
  369.             case 'g':
  370.                 cptr = _gtoa(va_arg(aptr, double), maxlen);
  371.                 aptr += sizeof(double);
  372.                 maxlen = 1024;
  373.                 break;
  374.             case 'l':
  375.                 fptr++;
  376.                 goto doagain;
  377.                 break;
  378.             case 'o':
  379.                 cptr = _itoa(va_arg(aptr, int), 8);
  380.                 aptr += sizeof(int);
  381.                 break;
  382.             case 's':
  383.                 cptr = va_arg(aptr, char *);
  384.                 aptr += sizeof(char *);
  385.                 if (cptr == NULL)
  386.                     cptr = "(null)";
  387.                 break;
  388.             case 'u':
  389.                 cptr = _itoa(va_arg(aptr, unsigned), 10);
  390.                 aptr += sizeof(unsigned);
  391.                 break;
  392.             case 'x':
  393.                 tptr = cptr = _itoa(va_arg(aptr, int), 16);
  394.                 while (*tptr) {
  395.                     if (isupper(*tptr))
  396.                         *tptr = tolower(*tptr);
  397.                     tptr++;
  398.                 }
  399.                 aptr += sizeof(int);
  400.                 break;
  401.             case 'X':
  402.                 cptr = _itoa(va_arg(aptr, int), 16);
  403.                 aptr += sizeof(int);
  404.                 break;
  405.             default:
  406.                 cptr = "-OOPS-";
  407.                 break;
  408.             }
  409.             if (strlen(cptr) > maxlen)
  410.                 cptr[maxlen] = '\0';
  411.             cptr = _justify(cptr, width, pad);
  412.             while (*cptr)
  413.                 *buffer++ = *cptr++;
  414.             break;
  415.         default:
  416.             *buffer++ = *fptr;
  417.             break;
  418.         }
  419.         fptr++;
  420.     }
  421.     *buffer = '\0';
  422. }
  423.  
  424. char           *
  425. sprintf(buf, fmt, args)
  426.     char           *buf, *fmt;
  427.     void           *args;
  428. {
  429.     _doprnt(fmt, &args, buf);
  430.     return (buf);
  431. }
  432.  
  433. fprintf(fp, fmt, args)
  434.     FILE           *fp;
  435.     char           *fmt;
  436.     void           *args;
  437. {
  438.     char           *buffer = _doprntbuf;
  439.  
  440.     _doprnt(fmt, &args, buffer);
  441.     fwrite(buffer, 1, strlen(buffer), fp);
  442. }
  443.  
  444. printf(fmt, args)
  445.     char           *fmt;
  446.     void           *args;
  447. {
  448.     char           *buffer = _doprntbuf;
  449.  
  450.     _doprnt(fmt, &args, buffer);
  451.     fwrite(buffer, 1, strlen(buffer), stdout);
  452. }
  453.